import 'dart:convert';
import 'package:injectable/injectable.dart';
import 'package:vista/shared/models/message_shot.dart';
import 'package:vista/shared/models/user_frame.dart';
import 'package:vista/shared/services/storage_service.dart';
import 'package:vista/shared/services/auth_focus.dart';

/// 对话镜头
/// 处理单聊消息的发送、接收、已读状态，如摄影中的镜头般聚焦对话
@lazySingleton
class DialogLens {
  final StorageService _storageService;
  final AuthFocus _authFocus;
  static const String _messagesPrefix = 'chat_messages_';
  static const String _isInitializedKey = 'chats_initialized';

  DialogLens(this._storageService, this._authFocus);

  /// 初始化默认聊天数据
  /// 围绕 admin 用户创建一些默认的聊天消息
  Future<void> initializeDefaultChats() async {
    final isInitialized = await _storageService.retrieveBool(_isInitializedKey);
    if (isInitialized == true) {
      return; // 已经初始化过了
    }

    final users = await _authFocus.getUsers();
    if (users.isEmpty) {
      return;
    }

    // 找到 admin 用户
    UserFrame? adminUser;
    try {
      adminUser = await _authFocus.findUserByAccount('admin');
    } catch (e) {
      return; // 找不到 admin 用户
    }

    // 创建默认聊天消息
    // admin 与其他几个用户的对话
    final defaultMessages = <MessageShot>[];

    // 获取一些其他用户用于创建对话
    final otherUsers =
        users.where((u) => u.account != 'admin').take(3).toList();
    if (otherUsers.isEmpty) {
      return;
    }

    final now = DateTime.now();

    // admin 与用户1的对话
    if (otherUsers.isNotEmpty) {
      final user1 = otherUsers[0];
      defaultMessages.add(
        MessageShot(
          id: 'msg_${now.millisecondsSinceEpoch}_1',
          senderId: adminUser.id,
          receiverId: user1.id,
          type: MessageType.text,
          content: 'Hi, how are you doing?',
          timestamp: now.subtract(const Duration(hours: 2)),
          isRead: true,
        ),
      );
      defaultMessages.add(
        MessageShot(
          id: 'msg_${now.millisecondsSinceEpoch}_2',
          senderId: user1.id,
          receiverId: adminUser.id,
          type: MessageType.text,
          content: 'I\'m doing great! Thanks for asking.',
          timestamp: now.subtract(const Duration(hours: 1, minutes: 50)),
          isRead: true,
        ),
      );
      defaultMessages.add(
        MessageShot(
          id: 'msg_${now.millisecondsSinceEpoch}_3',
          senderId: adminUser.id,
          receiverId: user1.id,
          type: MessageType.text,
          content: 'Would you like to share some photos?',
          timestamp: now.subtract(const Duration(hours: 1, minutes: 30)),
          isRead: true,
        ),
      );
      defaultMessages.add(
        MessageShot(
          id: 'msg_${now.millisecondsSinceEpoch}_4',
          senderId: user1.id,
          receiverId: adminUser.id,
          type: MessageType.text,
          content: 'Sure! Let me send you some later.',
          timestamp: now.subtract(const Duration(minutes: 45)),
          isRead: false, // 未读消息
        ),
      );
    }

    // admin 与用户2的对话（包含拨打失败消息）
    if (otherUsers.length >= 2) {
      final user2 = otherUsers[1];
      defaultMessages.add(
        MessageShot(
          id: 'msg_${now.millisecondsSinceEpoch}_5',
          senderId: adminUser.id,
          receiverId: user2.id,
          type: MessageType.text,
          content: 'Hello! Are you available for a call?',
          timestamp: now.subtract(const Duration(hours: 3)),
          isRead: true,
        ),
      );
      defaultMessages.add(
        MessageShot(
          id: 'msg_${now.millisecondsSinceEpoch}_6',
          senderId: adminUser.id,
          receiverId: user2.id,
          type: MessageType.callFailed,
          content: 'Call failed',
          timestamp: now.subtract(const Duration(hours: 2, minutes: 30)),
          isRead: true,
        ),
      );
      defaultMessages.add(
        MessageShot(
          id: 'msg_${now.millisecondsSinceEpoch}_7',
          senderId: user2.id,
          receiverId: adminUser.id,
          type: MessageType.text,
          content: 'Sorry, I was busy. Can we try again?',
          timestamp: now.subtract(const Duration(minutes: 20)),
          isRead: false, // 未读消息
        ),
      );
    }

    // admin 与用户3的对话（只有拨打失败）
    if (otherUsers.length >= 3) {
      final user3 = otherUsers[2];
      defaultMessages.add(
        MessageShot(
          id: 'msg_${now.millisecondsSinceEpoch}_8',
          senderId: adminUser.id,
          receiverId: user3.id,
          type: MessageType.callFailed,
          content: 'Call failed',
          timestamp: now.subtract(const Duration(hours: 5)),
          isRead: true,
        ),
      );
      defaultMessages.add(
        MessageShot(
          id: 'msg_${now.millisecondsSinceEpoch}_9',
          senderId: adminUser.id,
          receiverId: user3.id,
          type: MessageType.text,
          content: 'Let me know when you\'re free.',
          timestamp: now.subtract(const Duration(hours: 4, minutes: 50)),
          isRead: true,
        ),
      );
      defaultMessages.add(
        MessageShot(
          id: 'msg_${now.millisecondsSinceEpoch}_10',
          senderId: user3.id,
          receiverId: adminUser.id,
          type: MessageType.text,
          content: 'I\'ll call you back later.',
          timestamp: now.subtract(const Duration(minutes: 10)),
          isRead: false, // 未读消息
        ),
      );
    }

    // 按聊天会话分组保存消息，避免重复
    final messagesByChat = <String, List<MessageShot>>{};
    for (final message in defaultMessages) {
      final chatKey = _getChatKey(message.senderId, message.receiverId);
      if (!messagesByChat.containsKey(chatKey)) {
        messagesByChat[chatKey] = [];
      }
      // 检查是否已存在相同的消息ID
      if (!messagesByChat[chatKey]!.any((msg) => msg.id == message.id)) {
        messagesByChat[chatKey]!.add(message);
      }
    }

    // 批量保存每个聊天会话的消息
    for (final entry in messagesByChat.entries) {
      final chatKey = entry.key;
      final messages = entry.value;
      // 按时间戳排序
      messages.sort((a, b) => a.timestamp.compareTo(b.timestamp));
      await _saveMessages(chatKey, messages);
    }

    await _storageService.persistBool(_isInitializedKey, true);
  }

  /// 获取两个用户之间的聊天消息列表
  /// [userId1] 用户1的ID
  /// [userId2] 用户2的ID
  Future<List<MessageShot>> getChatMessages({
    required String userId1,
    required String userId2,
  }) async {
    final chatKey = _getChatKey(userId1, userId2);
    final messagesString = await _storageService.retrieveString(chatKey);
    if (messagesString == null) {
      return [];
    }

    try {
      final List<dynamic> messagesJson = _parseMessagesJson(messagesString);
      final messages =
          messagesJson
              .map((json) => MessageShot.fromJson(json as Map<String, dynamic>))
              .toList();

      // 去重：根据消息ID去重，保留第一个
      final uniqueMessages = <String, MessageShot>{};
      for (final message in messages) {
        if (!uniqueMessages.containsKey(message.id)) {
          uniqueMessages[message.id] = message;
        }
      }

      final result = uniqueMessages.values.toList();
      result.sort((a, b) => a.timestamp.compareTo(b.timestamp));
      return result;
    } catch (e) {
      return [];
    }
  }

  /// 发送文本消息
  Future<MessageShot> sendTextMessage({
    required String senderId,
    required String receiverId,
    required String content,
  }) async {
    final message = MessageShot(
      id: 'msg_${DateTime.now().millisecondsSinceEpoch}_$senderId',
      senderId: senderId,
      receiverId: receiverId,
      type: MessageType.text,
      content: content,
      timestamp: DateTime.now(),
      isRead: false,
    );

    await _addMessage(message);
    return message;
  }

  /// 发送拨打失败消息
  Future<MessageShot> sendCallFailedMessage({
    required String senderId,
    required String receiverId,
  }) async {
    final message = MessageShot(
      id: 'msg_${DateTime.now().millisecondsSinceEpoch}_${senderId}_call',
      senderId: senderId,
      receiverId: receiverId,
      type: MessageType.callFailed,
      content: 'Call failed',
      timestamp: DateTime.now(),
      isRead: false,
    );

    await _addMessage(message);
    return message;
  }

  /// 标记消息为已读
  Future<void> markMessageAsRead(String messageId, String userId) async {
    // 获取所有用户的聊天记录
    final allUsers = await _authFocus.getUsers();

    for (final user in allUsers) {
      if (user.id == userId) continue;

      final chatKey1 = _getChatKey(userId, user.id);
      final chatKey2 = _getChatKey(user.id, userId);

      // 检查两个方向的聊天
      for (final chatKey in [chatKey1, chatKey2]) {
        final messagesString = await _storageService.retrieveString(chatKey);
        if (messagesString == null) continue;

        try {
          final messagesJson = _parseMessagesJson(messagesString);
          final messages =
              messagesJson
                  .map(
                    (json) =>
                        MessageShot.fromJson(json as Map<String, dynamic>),
                  )
                  .toList();

          bool updated = false;
          for (int i = 0; i < messages.length; i++) {
            if (messages[i].id == messageId &&
                messages[i].receiverId == userId &&
                !messages[i].isRead) {
              messages[i] = messages[i].copyWithRead(true);
              updated = true;
            }
          }

          if (updated) {
            await _saveMessages(chatKey, messages);
          }
        } catch (e) {
          continue;
        }
      }
    }
  }

  /// 标记与某个用户的所有消息为已读
  Future<void> markAllMessagesAsRead({
    required String userId,
    required String otherUserId,
  }) async {
    final messages = await getChatMessages(
      userId1: userId,
      userId2: otherUserId,
    );

    final unreadMessages =
        messages
            .where((msg) => msg.receiverId == userId && !msg.isRead)
            .toList();

    if (unreadMessages.isEmpty) {
      return;
    }

    final chatKey = _getChatKey(userId, otherUserId);
    final messagesString = await _storageService.retrieveString(chatKey);
    if (messagesString == null) {
      return;
    }

    try {
      final messagesJson = _parseMessagesJson(messagesString);
      final allMessages =
          messagesJson
              .map((json) => MessageShot.fromJson(json as Map<String, dynamic>))
              .toList();

      for (int i = 0; i < allMessages.length; i++) {
        if (allMessages[i].receiverId == userId && !allMessages[i].isRead) {
          allMessages[i] = allMessages[i].copyWithRead(true);
        }
      }

      await _saveMessages(chatKey, allMessages);
    } catch (e) {
      // 忽略错误
    }
  }

  /// 获取未读消息数量
  Future<int> getUnreadCount(String userId) async {
    final allUsers = await _authFocus.getUsers();
    int totalUnread = 0;

    for (final user in allUsers) {
      if (user.id == userId) continue;
      final messages = await getChatMessages(userId1: userId, userId2: user.id);
      totalUnread +=
          messages
              .where((msg) => msg.receiverId == userId && !msg.isRead)
              .length;
    }

    return totalUnread;
  }

  /// 获取与某个用户的未读消息数量
  Future<int> getUnreadCountWithUser({
    required String userId,
    required String otherUserId,
  }) async {
    final messages = await getChatMessages(
      userId1: userId,
      userId2: otherUserId,
    );
    return messages
        .where((msg) => msg.receiverId == userId && !msg.isRead)
        .length;
  }

  /// 获取所有聊天会话列表（返回有对话的用户ID列表）
  Future<List<String>> getChatSessions(String userId) async {
    final allUsers = await _authFocus.getUsers();
    final sessionsWithTime = <MapEntry<String, DateTime>>[];

    for (final user in allUsers) {
      if (user.id == userId) continue;
      final messages = await getChatMessages(userId1: userId, userId2: user.id);
      if (messages.isNotEmpty) {
        final lastMessage = messages.last;
        sessionsWithTime.add(MapEntry(user.id, lastMessage.timestamp));
      }
    }

    // 按最后一条消息时间排序（最新的在前）
    sessionsWithTime.sort((a, b) => b.value.compareTo(a.value));

    return sessionsWithTime.map((entry) => entry.key).toList();
  }

  /// 获取聊天会话的最后一条消息
  Future<MessageShot?> getLastMessage({
    required String userId1,
    required String userId2,
  }) async {
    final messages = await getChatMessages(userId1: userId1, userId2: userId2);
    return messages.isNotEmpty ? messages.last : null;
  }

  /// 添加消息到存储
  Future<void> _addMessage(MessageShot message) async {
    final chatKey = _getChatKey(message.senderId, message.receiverId);
    final messages = await getChatMessages(
      userId1: message.senderId,
      userId2: message.receiverId,
    );
    // 检查消息是否已存在（根据ID）
    if (messages.any((msg) => msg.id == message.id)) {
      return; // 消息已存在，不重复添加
    }
    messages.add(message);
    await _saveMessages(chatKey, messages);
  }

  /// 保存消息列表
  Future<void> _saveMessages(String chatKey, List<MessageShot> messages) async {
    final messagesJson = messages.map((msg) => msg.toJson()).toList();
    final messagesString = _encodeMessagesJson(messagesJson);
    await _storageService.persistString(chatKey, messagesString);
  }

  /// 生成聊天键（确保顺序一致）
  String _getChatKey(String userId1, String userId2) {
    final sorted = [userId1, userId2]..sort();
    return '$_messagesPrefix${sorted[0]}_${sorted[1]}';
  }

  /// 解析消息JSON
  List<dynamic> _parseMessagesJson(String jsonString) {
    try {
      return jsonDecode(jsonString) as List<dynamic>;
    } catch (e) {
      return [];
    }
  }

  /// 编码消息JSON
  String _encodeMessagesJson(List<Map<String, dynamic>> messages) {
    return jsonEncode(messages);
  }

  /// 删除两个用户之间的所有消息
  /// [userId1] 用户1的ID
  /// [userId2] 用户2的ID
  Future<void> deleteAllMessages({
    required String userId1,
    required String userId2,
  }) async {
    final chatKey = _getChatKey(userId1, userId2);
    await _storageService.removeKey(chatKey);
  }
}
